Skip to content

Spec docs: audit fixes, and duplicate-content-id emitted - #265

Merged
mpigsley merged 6 commits into
mainfrom
docs/spec
Nov 2, 2026
Merged

mpigsley merged 6 commits into
mainfrom
docs/spec

Conversation

@mpigsley

@mpigsley mpigsley commented Nov 2, 2026

Copy link
Copy Markdown
Contributor

Fixes the spec docs audit (about 107 findings), re-checked against main after #257 and #262. Each statement was checked against the engine, schemas, data and packs. Changed and new examples were run through the current engine.

Code (own commit)

  • Engine: loadRuleset now reports duplicate-content-id (data id, pack) when two content items of one pack share an ID. Before, the code was published but never emitted, and the later item replaced the earlier one silently. Adds a conformance case and a patch changeset for spec and engine.

Docs, by file

  • engine-core.md
  • engine-interface.md
    • setField in the change types and in copy queries.
    • appliers on the five calls that take it.
    • Error kinds formula and build.
    • Full shapes for choices (type, inactive), offers (create) and the applyChanges output.
    • Rules-issue IDs, and unchoose by owner.
  • upgrades.md
    • Steps that remove a pick also remove its addAs: copy copy, and adoptStandard skips pick copies.
    • Narrowing now lists a grant's available and added bounds.
    • A given parameter that becomes derived is param-type-changed.
    • A bounds-only params entry isn't a parameter of the pack that declares it.
    • Notes on change IDs and state-removed renames, and a cleaned-up interface-change paragraph.
  • effects.md
    • Ops table: a params row, the current changes and option value shapes, and fields targets.
    • Property table: scope, plus the full target and value.
    • effectsWhen applies to holder effects only.
    • Changes steps take the ops changes and action.
    • Stacking wording.
    • Examples follow the packs: effectsWhen gates and Vexed with appliedBy: self.
    • A pointer from an incoming then to batch-scoped situational copy-state costs (Spec: a situational choice's changes reach held copies' state (#244) #257).
  • content.md
    • Content items and Choices tables are complete.
    • The Null Field aura now copies the pack (it broke link-field-mismatch).
    • The elemental connection example uses an ID literal.
    • Aura gates, the rules-level immunity owner, of: integer errors, the copyNames link and the type label.
  • characters.md: who fills in appliedBy.
  • display-hints.md: an unavailable activation is still a content-group member.
  • dice-and-actions.md
    • The Fate outcome example is now valid (it gains a result).
    • Reactions go through situational choices.
    • to: applied in the steps table and the finished-action routing; it is dropped from the from routes.
    • Action scope and label, roll part and roll item properties, allocate tags and prompt, and the dNz and comparison notations.
    • Every safety limit, recommend: '#done', and the stray "(0100)"/"(0108)" removed.
    • The parameter conflict wording, and release notes for params.
    • Healing Grace bounds spend with graceEnd.
    • Clock actions and content action effects.
  • engine-actions.md
    • The errors startAction throws: invalid-param, unknown-follow-up, unknown-reference, not-addable, unknown-role, unknown-tag and invalid-face.
    • Allocate tags in the policy.
    • self computed values.
    • Situational choices with incoming.
    • Log fields for a rolled amount.
  • formulas.md
    • appliedBy, the applier bound-in row, and grant and i types.
    • Roots of changes and action effects, derived parameters, and a situational choice's copy changes (Spec: a situational choice's changes reach held copies' state (#244) #257).
    • steps values and group passes, and release.where.
    • Every missing expected type: band total, aura size, follow-up character, appliedBy, activeWhen, effectsWhen, param bounds and a derived formula.
    • Aggregate and fixed-root lists.
  • i18n.md and the en.yaml header
  • packs.md
    • LicenseRef- licenses: credit and the permission notice, which the build doesn't check.
    • The 5e/srd-5.2 path.
    • The full rules-document list, and params effects in extensions.
  • README.md: "the official packs of a dozen games", the doc-map rows, and what a fixed set's specVersion means.
  • rules-and-fields.md: the intro topic list, and the reaction wording now matches its example.
  • versioning.md: a fixed set's specVersion stays when the version moves.
  • Data descriptions

Each area has a patch changeset for @opencharacter/spec.

Skipped

Found, not fixed here (follow-ups)

  • Checker vs engine: the formula checker types a roll effect's roll with total, faces, kept and empty. At run time the engine binds only item, self and tags, so such a formula loads and then fails.
  • Clock actions: load doesn't check content's op: action effects at a clock action's tagged steps. One that hands off, or runs an action with a choice, allocate or handoff step, makes the clock action pause. This needs an issue (invalid-clock-action at load).
  • packages/text: typeKey ignores a content type's label, which the validator honours.
  • Packs: draw-steel-heroes Healing Grace still bounds graceRecoveries rather than spend. 5e-srd-5.2 Vexed still uses flags.me.

Checks

pnpm check passes. One timing test flaked under load and passes on its own. pnpm build:website checks 2024 links with 0 broken. pnpm release:check passes.

@mpigsley
mpigsley requested a review from a team as a code owner November 2, 2026 17:59
… pack with one ID

The code was published but never emitted: the later item replaced the
earlier silently.

Signed-off-by: Mitchel Pigsley <mpigsley@gmail.com>
Aura entries, unknown-situational on an adjust, the pack limit on fields
queries, setField, appliers, error kinds, output shapes, pick copies in
upgrade steps, derived parameters and added bounds in release checks; the
change-type, rules-issue, upgrade-step and error-code descriptions.

Signed-off-by: Mitchel Pigsley <mpigsley@gmail.com>
…ormat

Ops and property tables, examples that match the packs, every content
item and choice property, effectsWhen scope, and the batch route for a
once-per-attack copy-state cost; effect-operation, stacking-policy and
applied.aura descriptions.

Signed-off-by: Mitchel Pigsley <mpigsley@gmail.com>
…gine

Every root and expected type in formulas.md, the invalid-added-param
reasons and added-parameter names in i18n, LicenseRef- licenses in
packs.md, an up-to-date README and rules-and-fields intro.

Signed-off-by: Mitchel Pigsley <mpigsley@gmail.com>
to: applied routing, reactions as situational choices, action scope and
label, roll part and roll item properties, dice notation forms, every
safety limit and startAction error; a valid Fate example.

Signed-off-by: Mitchel Pigsley <mpigsley@gmail.com>
Signed-off-by: Mitchel Pigsley <mpigsley@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant